home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
c
/
nos042_s
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-16
|
17KB
|
801 lines
/* Main-level NOS program:
* initialization
* keyboard processing
* generic user commands
*
* Copyright 1991 Phil Karn, KA9Q
*/
/****************************************************************************
* $Id: main.c 1.5 94/01/04 14:09:37 ROOT_DOS Exp $
* 14 Jul 93 1.4 GT Banner changes. *
* 07 Nov 93 1.5 GT Prompt global. *
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*
* __stdargs dosourceb, domore
* dosource, dosurceb call do_source to avoid reg/std call sequecne problems
*
****************************************************************************/
#include <stdio.h>
#include <time.h>
#if defined(__TURBOC__) && defined(MSDOS)
#include <io.h>
#include <conio.h>
#endif
#include "global.h"
#ifdef ANSIPROTO
#include <stdarg.h>
#endif
#ifdef ATARI
#include <unistd.h>
#endif
#include "mbuf.h"
#include "timer.h"
#include "proc.h"
#include "iface.h"
#include "ip.h"
#include "tcp.h"
#include "udp.h"
#include "ax25.h"
#include "kiss.h"
#include "enet.h"
#include "netrom.h"
#include "ftpcli.h"
#include "telnet.h"
#include "tty.h"
#include "session.h"
#include "hardware.h"
#include "usock.h"
#include "socket.h"
#include "cmdparse.h"
#include "commands.h"
#include "daemon.h"
#include "devparam.h"
#include "domain.h"
#include "files.h"
#include "main.h"
#include "remote.h"
#include "trace.h"
extern struct cmds far Cmds[], Startcmds[],Stopcmds[],Attab[];
#ifdef MSDOS
int Escape = 324; /* MSDOS escape character is F10 */
#else
#ifdef ATARI
int Escape = 0x44; /* default excape character is F10 */
#else
char Escape = 0x1d; /* default escape character is ^] */
#endif
#endif
char Badhost[] = "Unknown host %s\n";
char *Hostname;
char Nospace[] = "No space!!\n"; /* Generic malloc fail message */
struct proc *Cmdpp;
struct proc *Display;
int main_exit = FALSE; /* from main program (flag) */
#ifndef ATARI
char Prompt[] = "net> ";
#else
char Prompt[] = "\x08\x08NET > ";
#endif
static FILE *Logfp;
static time_t StartTime; /* time that NOS was started */
static int Verbose;
static char banner1[] = "Based on KA9Q NOS by Phil Karn - %s\n";
static char banner2[] = "Copyright 1991 Phil Karn. ";
static char banner3[] = "Parts copyright 1992, 1993 Demon Internet & Members\n\n";
static char banner4[] = "Support: mail internet@demon.net or phone 081 343 3881\n";
int main(int argc, char *argv[])
{
char *inbuf,*intmp;
FILE *fp;
struct daemon *tp;
struct mbuf *bp;
int c;
int rootset = 0;
StartTime = time(&StartTime);
while((c = getopt(argc, argv, "s:d:bv")) != EOF){
switch(c){
case 's': /* Number of sockets */
Nusock = atoi(optarg);
break;
case 'd': /* Root directory for various files */
rootset = 1;
initroot(optarg);
break;
case 'b': /* Use BIOS for screen output */
#ifdef __TURBOC__
directvideo = 0;
#endif
break;
case 'v':
Verbose = 1;
break;
case '?': /* illegal option found */
printf("usage: %s [-s num] [-d dir] [-v] [startup] \n", argv[0]);
printf("where num = number of sockets, default=%d \n", Nusock);
printf(" dir = root directory for nos, default=\\ \n");
printf(" -v = verbose flag \n");
printf(" startup = startup file, default=%s\n", Startup);
return -1; /* give up and exit */
}
}
if(!rootset) { /* set route from env - DFN */
char *root;
if ((root = getenv("NOS_ROOT")))
initroot(root);
else
initroot("\\");
}
kinit();
ipinit();
ioinit();
sockinit();
Cmdpp = mainproc("cmdintrp");
Sessions = (struct session *)callocw(Nsessions, sizeof(struct session));
Command = Lastcurr = newsession("command interpreter", COMMAND);
Display = newproc("display", 250, display, 0, NULLCHAR, NULL, 0);
tprintf("\033E"); /* clear the screen */
tprintf("%s %s %s\n\n", atari_ver1, atari_ver2, atari_ver3);
tprintf(banner1, Version);
tprintf(banner2);
tprintf(banner3);
/*
tprintf(banner4);
*/
log(-1,"Load address %X \n", main);
rflush();
/* Start background Daemons */
for (tp = Daemons; ; tp++) {
if (tp->name == NULLCHAR)
break;
newproc(tp->name, tp->stksize, tp->fp, 0, NULLCHAR, NULL, 0);
}
if (optind < argc) {
/* Read startup file named on command line */
if ((fp = fopen(argv[optind], READ_TEXT)) == NULLFILE)
tprintf("Can't read config file %s: %s\n",
argv[optind],strerror(errno));
} else {
fp = fopen(Startup,READ_TEXT);
}
if(fp != NULLFILE){
inbuf = mallocw(BUFSIZ);
intmp = mallocw(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
if(Verbose)
tprintf("%s",intmp);
if(cmdparse(Cmds,inbuf,NULL) != 0){
tprintf("input line: %s",intmp);
}
}
fclose(fp);
free(inbuf);
free(intmp);
}
/* Now loop forever, processing commands */
for( ; ; ) {
tprintf(Prompt);
usflush(Command->output);
if (recv_mbuf(Command->input, &bp, 0, NULLCHAR, 0) != -1) {
(void)cmdparse(Cmds, bp->data, Lastcurr);
free_p(bp);
}
}
return 0;
}
/*
keyboard - Keyboard input process
*/
void keyboard(int i, void *v1, void *v2)
{
int c;
struct mbuf *bp;
Current->cur_pos = 0;
/* Keyboard process loop */
for( ; ; ) {
c = kbread();
if (c == -2 && Current != Command) {
/* Save current tty mode and set cooked */
#ifndef ATARI
swapscreen(Current,Command);
#else
alert(Display, 1);
#endif
Lastcurr = Current;
Current = Command;
}
Current->row = MOREROWS;
psignal(&Current->row, 1);
if(c >= 0) {
/* If the screen driver was in morewait state, this char
* has woken him up. Toss it so it doesn't also get taken
* as normal input. If the char was a command escape,
* however, it will be accepted; this gives the user
* a way out of lengthy output.
*/
if (!Current->morewait && (bp = ttydriv(Current,c)) != NULLBUF) {
send_mbuf(Current->input, bp, 0, NULLCHAR, 0);
Current->cur_pos = 0;
}
}
}
}
/*
dodelete - Delete a file
*/
int dodelete(int argc, char *argv[], void *p)
{
int i;
for(i = 1; i < argc; i++) {
if(unlink(argv[i]) == -1) {
tprintf("Can't delete %s: %s\n",
argv[i],strerror(errno));
}
}
return 0;
}
int
dorename(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(rename(argv[1],argv[2]) == -1)
tprintf("Can't rename: %s\n",strerror(errno));
return 0;
}
int
doexit(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int i;
time_t StopTime;
StopTime = time(&StopTime);
main_exit = TRUE; /* let everyone know we're out of here */
reset_all();
if(Dfile_updater != NULLPROC)
alert(Dfile_updater,0); /* don't wait for timeout */
for(i=0;i<100;i++)
pwait(NULL); /* Allow tasks to complete */
shuttrace();
log(-1,"NOS was stopped at %s", ctime(&StopTime));
if(Logfp){
fclose(Logfp);
Logfp = NULLFILE;
}
iostop();
exit(0);
return 0; /* To satisfy lint */
}
int
dohostname(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2)
tprintf("%s\n",Hostname);
else {
struct iface *ifp;
char *name;
if((ifp = if_lookup(argv[1])) != NULLIF){
if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
tprintf("Interface address not resolved\n");
return 1;
} else {
if(Hostname != NULLCHAR)
free(Hostname);
Hostname = name;
/* remove trailing dot */
if ( Hostname[strlen(Hostname)] == '.' ) {
Hostname[strlen(Hostname)] = '\0';
}
tprintf("Hostname set to %s\n", name );
}
} else {
if(Hostname != NULLCHAR)
free(Hostname);
Hostname = strdup(argv[1]);
}
}
return 0;
}
int
dolog(argc,argv,p)
int argc;
char *argv[];
void *p;
{
static char *logname;
if(argc < 2){
if(Logfp)
tprintf("Logging to %s\n",logname);
else
tprintf("Logging off\n");
return 0;
}
if(Logfp){
log(-1,"NOS log closed");
fclose(Logfp);
Logfp = NULLFILE;
free(logname);
logname = NULLCHAR;
}
if(strcmp(argv[1],"stop") != 0){
logname = strdup(argv[1]);
Logfp = fopen(logname,APPEND_TEXT);
log(-1,"NOS was started at %s", ctime(&StartTime));
#ifdef ATARI
log(-1, "NOS Load address: %x ", main);
#endif
#ifdef MSDOS
log(-1,"NOS load information: CS=0x%04x DS=0x%04x", _CS, _DS);
#endif
}
return 0;
}
/*
dosource - stub function for do_source with __regargs linkage
*/
int dosource(int argc, char *argv[], void *p)
{
return do_source(argc, argv, p);
}
/*
dosourceb - stub function for do_source with _-stdargs linkage
*/
int __stdargs dosourceb(int argc, char *argv[], void *p)
{
return do_source(argc, argv, p);
}
/*
do_source - replaces dosource in pc ka9q, called via stub functions to
fixup the linkage.
*/
static int do_source(int argc, char *argv[], void *p)
{
int linenum = 0;
char *inbuf,*intmp, *p1, *p2;
FILE *fp;
/* Read command source file */
if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
tprintf("Can't read %s: %s\n",argv[1],strerror(errno));
return 1;
}
p1 = inbuf = malloc(BUFSIZ);
p2 = intmp = malloc(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
linenum++;
if(Verbose)
tprintf("%s",intmp);
if(cmdparse(Cmds,inbuf,NULL) != 0){
tprintf("*** file \"%s\", line %d: %s\n",
argv[1],linenum,intmp);
}
}
fclose(fp);
free(p1);
free(p2);
return 0;
}
int
dohelp(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct cmds *cmdp;
int i;
char buf[66];
tprintf(banner1, Version);
tprintf(banner2);
tprintf(banner3);
tprintf(banner4);
tprintf("Main commands:\n");
memset(buf,' ',sizeof(buf));
buf[64] = '\n';
buf[65] = '\0';
for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
if(i == 3){
tprintf(buf);
memset(buf,' ',sizeof(buf));
buf[64] = '\n';
buf[65] = '\0';
}
}
if(i != 0)
tprintf(buf);
return 0;
}
/* Attach an interface
* Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
*/
int
doattach(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return subcmd(Attab,argc,argv,p);
}
/* Manipulate I/O device parameters */
int
doparam(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct iface *ifp;
int param,set;
int32 val;
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(ifp->ioctl == NULL){
tprintf("Not supported\n");
return 1;
}
if(argc < 3){
for(param=1;param<=16;param++){
val = (*ifp->ioctl)(ifp,param,FALSE,0L);
if(val != -1)
tprintf("%s: %ld\n",parmname(param),val);
}
return 0;
}
param = devparam(argv[2]);
if(param == -1){
tprintf("Unknown parameter %s\n",argv[2]);
return 1;
}
if(argc < 4){
set = FALSE;
val = 0L;
} else {
set = TRUE;
val = atol(argv[3]);
}
val = (*ifp->ioctl)(ifp,param,set,val);
if(val == -1){
tprintf("Parameter %s not supported\n",argv[2]);
} else {
tprintf("%s: %ld\n",parmname(param),val);
}
return 0;
}
/* Display or set IP interface control flags */
int
domode(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct iface *ifp;
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(argc < 3){
tprintf("%s: %s\n",ifp->name,
(ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
return 0;
}
switch(argv[2][0]){
case 'v':
case 'c':
case 'V':
case 'C':
ifp->flags = CONNECT_MODE;
break;
case 'd':
case 'D':
ifp->flags = DATAGRAM_MODE;
break;
default:
tprintf("Usage: %s [vc | datagram]\n",argv[0]);
return 1;
}
return 0;
}
int
doescape(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2)
tprintf("%d\n",Escape);
else if (strlen(argv[1]) == 1)
Escape = *argv[1];
else Escape = atoi(argv[1]);
return 0;
}
/* Generate system command packet. Synopsis:
* remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
*/
int
doremote(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct sockaddr_in fsock;
int s,c;
char *data,x;
int16 port,len;
char *key = NULLCHAR;
int klen;
int32 addr = 0;
char *cmd,*host;
port = IPPORT_REMOTE; /* Set default */
optind = 1; /* reinit getopt() */
while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
switch(c){
case 'a':
addr = resolve(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'k':
key = optarg;
klen = strlen(key);
break;
case 's':
Rempass = strdup(optarg);
return 0; /* Only set local password */
}
}
if(optind > argc - 2){
tprintf("Insufficient args\n");
return -1;
}
host = argv[optind++];
cmd = argv[optind];
if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
tprintf("socket failed\n");
return 1;
}
len = 1;
/* Did the user include a password or kickme target? */
if(addr != 0)
len += sizeof(int32);
if(key != NULLCHAR)
len += klen;
if(len == 1)
data = &x;
else
data = mallocw(len);
fsock.sin_family = AF_INET;
fsock.sin_addr.s_addr = resolve(host);
fsock.sin_port = port;
switch(cmd[0]){
case 'r':
data[0] = SYS_RESET;
if(key != NULLCHAR)
strncpy(&data[1],key,klen);
break;
case 'e':
data[0] = SYS_EXIT;
if(key != NULLCHAR)
strncpy(&data[1],key,klen);
break;
case 'k':
data[0] = KICK_ME;
if(addr != 0)
put32(&data[1],addr);
break;
default:
tprintf("Unknown command %s\n",cmd);
goto cleanup;
}
/* Form the command packet and send it */
if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
tprintf("sendto failed: %s\n",strerror(errno));
goto cleanup;
}
cleanup:
if(data != &x)
free(data);
close_s(s);
return 0;
}
int __stdargs domore(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
FILE *fp;
char buf[81];
int row;
if((sp = newsession(argv[1],MORE)) == NULLSESSION){
return -1;
}
/* Put tty into raw mode so single-char responses will work */
sp->ttystate.echo = sp->ttystate.edit = 0;
if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
tprintf("Can't read %s\n",argv[1]);
keywait(NULLCHAR,1);
freesession(sp);
return 1;
}
row = MOREROWS;
while(fgets(buf,sizeof(buf),fp),!feof(fp)){
tprintf("%s",buf);
if(--row == 0){
row = keywait("--More--",0);
switch(row){
case -1:
case 'q':
case 'Q':
goto done;
case '\n':
case '\r':
row = 1;
break;
case ' ':
default:
row = MOREROWS;
}
}
}
done: fclose(fp);
keywait(NULLCHAR,1);
freesession(sp);
return 0;
}
/* No-op command */
int
donothing(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return 0;
}
/* Log messages of the form
* Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
*/
#if defined(ANSIPROTO)
void
log(int s,char *fmt, ...)
{
va_list ap;
char *cp;
long t;
int i;
struct sockaddr fsocket;
#if defined(MSDOS) || defined(ATARI)
int fd;
#endif
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
va_start(ap,fmt);
vfprintf(Logfp,fmt,ap);
va_end(ap);
fprintf(Logfp,"\n");
fflush(Logfp);
#if defined(MSDOS) || defined(ATARI)
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#else
/*VARARGS2*/
void
log(s,fmt,arg1,arg2,arg3,arg4,arg5)
int s;
char *fmt;
int arg1,arg2,arg3,arg4,arg5;
{
char *cp;
long t;
int fd,i;
struct sockaddr fsocket;
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
fprintf(Logfp,"\n");
fflush(Logfp);
#ifdef MSDOS
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#endif